// ------
// Nirvana Toolkit
// description: 自定义PlayableAsset，给技能编辑器的编辑载体入口
// ------

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Playables;

namespace Nirvana.SkillEditor
{
    [Serializable]
    public class SkillPlayableAsset : PlayableAsset, ISerializationCallbackReceiver
    {
        public MultiSkillActionInspector action = new MultiSkillActionInspector();
        [SerializeField] private string _serializedData;
        
        public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
        {
            var playable = ScriptPlayable<SkillPlayableBehaviour>.Create(graph);
            playable.GetBehaviour().skillPlayableAsset = this;
            return playable;
        }

        public void PrepareFrame(Playable playable, FrameData info)
        {
            action.PrepareFrame(playable, info);
        }

        public void ProcessFrame(Playable playable, FrameData info, object playerData)
        {
            action.ProcessFrame(playable, info, playerData);
        }
        
        #region JsonSerialize

        private static readonly JsonSerializerSettings Settings = new()
        {
            TypeNameHandling = TypeNameHandling.All,
            NullValueHandling = NullValueHandling.Ignore,
            DefaultValueHandling = DefaultValueHandling.Ignore,
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
            PreserveReferencesHandling = PreserveReferencesHandling.Objects,
            MissingMemberHandling = MissingMemberHandling.Ignore,
            Error = (sender, args) =>
            {
                Debug.LogError(args.ErrorContext.Error.Message);
                args.ErrorContext.Handled = true;
            }
        };

        public void OnBeforeSerialize()
        {
            _serializedData = Serialize(Formatting.Indented);
        }

        public void OnAfterDeserialize()
        {
            if (!string.IsNullOrEmpty(_serializedData))
            {
                Deserialize(_serializedData);
            }
            else
            {
                action = new MultiSkillActionInspector();
            }
        }

        public string Serialize(Formatting formatting = Formatting.None)
        {
            return JsonConvert.SerializeObject(action, formatting, Settings);
        }

        public void Deserialize(string json)
        {
            action = JsonConvert.DeserializeObject<MultiSkillActionInspector>(json, Settings) ?? new MultiSkillActionInspector();
        }

        #endregion
    }
}